{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "6c1kqMDxDodN"
   },
   "source": [
    "# Using Tools from Composio"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can also check this cookbook in colab [here](https://colab.research.google.com/drive/1x2FYThMPtQXLzKZAhf_Ry-oeU6oPygdm?usp=sharing)\n",
    "\n",
    "⭐ <i>Star us on [*Github*](https://github.com/camel-ai/camel), join our [*Discord*](https://discord.camel-ai.org) or follow our [*X*](https://x.com/camelaiorg)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "T1Ex1In8D1mm"
   },
   "source": [
    "*Goal: Star a repository on GitHub with natural language & CAMEL Agent*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "GluANG9QEH9N"
   },
   "source": [
    "### Install Packages & Connect a Tool"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "uXh7QEfsD91d"
   },
   "source": [
    "Integrate Composio with CAMEL agents to let them seamlessly interact with external apps"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "fEA7R7ycDjAR"
   },
   "source": [
    "Ensure you have the necessary packages installed and connect your GitHub account to allow your CAMEL-AI agents to utilize GitHub functionalities."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true,
    "id": "nswjAnDV8is0"
   },
   "outputs": [],
   "source": [
    "%pip install \"camel-ai[all]==0.1.6.5\"\n",
    "%pip install \"composio-camel -U\"\n",
    "\n",
    "import composio\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "ozJ6lR5L7OvU"
   },
   "outputs": [],
   "source": [
    "# Login to Composio\n",
    "!composio login"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "collapsed": true,
    "id": "RzU2mybwPzi4",
    "outputId": "44412d11-3755-4f99-c729-dcef739488eb"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[33mWarning: An existing connection for github was found.\u001b[0m\n",
      "\n",
      "> Do you want to replace the existing connection? (y, n): y\n",
      "\n",
      "\u001b[32m> Adding integration: Github\u001b[0m\u001b[32m...\u001b[0m\n",
      "\n",
      "Please authenticate github in the browser and come back here. URL: https://github.com/login/oauth/authorize?client_id=37beeaa7020925b04e40&redirect_uri=https%3A%2F%2Fbackend.composio.dev%2Fapi%2Fv1%2Fauth-apps%2Fadd&scope=repo%2Cadmin%3Aorg%2Cgist%2Cuser&state=production_eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb25uZWN0aW9uSWQiOiIwMWIyMTlmOC1kZTk5LTQ5ZWMtOTMwOS1mMzg3ZWFhMzRmNTgiLCJpbnRlZ3JhdGlvbklkIjoiMjdmNzM0YzAtZTIyMS00OTI1LTgxMjAtN2I1ZDNlYjAxOTA5IiwiYXBwTmFtZSI6ImdpdGh1YiIsImNsaWVudEluZm8iOnsiY2xpZW50SWQiOiJjZmE4NWM0ZC1jMWI0LTRjNmQtODE4Ni1kNmNiNmRmYmZlM2UifSwiaWF0IjoxNzIyMjE0NzUwfQ.w9QHilHJcHk8eIQa7vFCrGskC-VRFzgJIu1dQf4e7Jk&code_challenge=FnINCywVMtW7jH3DOGw6ddbmTf5vAJw5NvpojJkB2hs&code_challenge_method=S256\n",
      "⚠ Waiting for github authentication...\n",
      "✔ github added successfully!\n",
      "\u001b[32mShowing all apps\u001b[0m\n",
      "• multionai\n",
      "• typeform\n",
      "• dropbox\n",
      "• slack\n",
      "• yousearch\n",
      "• hackernews\n",
      "• scheduler\n",
      "• apify\n",
      "• googlecalendar\n",
      "• gmail\n",
      "• slackbot\n",
      "• attio\n",
      "• composio\n",
      "• okta\n",
      "• spotify\n",
      "• pagerduty\n",
      "• whatsapp\n",
      "• nasa\n",
      "• googledrive\n",
      "• googlesheets\n",
      "• googlemeet\n",
      "• inducedai\n",
      "• twilio\n",
      "• codeinterpreter\n",
      "• tavily\n",
      "• serpapi\n",
      "• snowflake\n",
      "• exa\n",
      "• zoom\n",
      "• listennotes\n",
      "• elevenlabs\n",
      "• brevo\n",
      "• weathermap\n",
      "• discord\n",
      "• soundcloud\n",
      "• perplexityai\n",
      "• splitwise\n",
      "• googledocs\n",
      "• firecrawl\n",
      "• strava\n",
      "• youtube\n",
      "• heroku\n",
      "• workable\n",
      "• taskade\n",
      "• googletasks\n",
      "• figma\n",
      "• clickup\n",
      "• linear\n",
      "• asana\n",
      "• trello\n",
      "• notion\n",
      "• zendesk\n",
      "• github\n"
     ]
    }
   ],
   "source": [
    "# Connect your Github account (this is a shell command, so it should be run in your terminal or with '!' prefix in a Jupyter Notebook)\n",
    "!composio add github\n",
    "\n",
    "# Check all different apps which you can connect with\n",
    "!composio apps"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "kPuvjgSaAAmb",
    "outputId": "75737d16-31b3-4b71-f5f4-37680fe7eff9"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[33m⚠️ Apps does not require update\u001b[0m\n",
      "\u001b[33m⚠️ Tags does not require update\u001b[0m\n",
      "\u001b[33m⚠️ Actions does not require update\u001b[0m\n",
      "\u001b[33m⚠️ Triggers does not require update\u001b[0m\n"
     ]
    }
   ],
   "source": [
    "# Update Composio apps\n",
    "! composio apps update"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "SN4hNVFJE6Cn"
   },
   "source": [
    "### Prepare your environment by initializing necessary imports from CAMEL & Composio."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "collapsed": true,
    "id": "9-q_q4JSPhDe",
    "outputId": "bf1e6a78-baec-4e98-dc99-bc937fc7d974"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Enter your API key: ··········\n"
     ]
    }
   ],
   "source": [
    "from typing import List\n",
    "\n",
    "from colorama import Fore\n",
    "from composio_camel import Action, ComposioToolSet\n",
    "\n",
    "from camel.agents.chat_agent import FunctionCallingRecord\n",
    "from camel.configs import ChatGPTConfig\n",
    "from camel.models import ModelFactory\n",
    "from camel.societies import RolePlaying\n",
    "from camel.types import ModelPlatformType, ModelType\n",
    "from camel.utils import print_text_animated\n",
    "\n",
    "import os\n",
    "from getpass import getpass\n",
    "\n",
    "# Prompt for the API key securely\n",
    "openai_api_key = getpass('Enter your API key: ')\n",
    "os.environ[\"OPENAI_API_KEY\"] = openai_api_key"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "85lpaPzeFagB"
   },
   "source": [
    "### Let's run CAMEL agents with tools from Composio!\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "A0Rsd2uzFqxq"
   },
   "outputs": [],
   "source": [
    "# Set your task\n",
    "\n",
    "task_prompt = (\n",
    "    \"I have created a new Github Repo,\"\n",
    "    \"Please star my github repository: camel-ai/camel\"\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "dWlqXlqMFtcY"
   },
   "outputs": [],
   "source": [
    "# Set Toolset\n",
    "\n",
    "composio_toolset = ComposioToolSet()\n",
    "\n",
    "tools = composio_toolset.get_actions(\n",
    "    actions=[Action.GITHUB_STAR_A_REPOSITORY_FOR_THE_AUTHENTICATED_USER]\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "uSVNE3x-Fy_F"
   },
   "outputs": [],
   "source": [
    "# Set models for user agent and assistant agent, give tool to the assistant\n",
    "\n",
    "assistant_agent_model = ModelFactory.create(\n",
    "    model_platform=ModelPlatformType.OPENAI,\n",
    "    model_type=ModelType.GPT_3_5_TURBO,\n",
    "    model_config_dict=ChatGPTConfig(tools=tools).as_dict(),\n",
    ")\n",
    "\n",
    "user_agent_model = ModelFactory.create(\n",
    "    model_platform=ModelPlatformType.OPENAI,\n",
    "    model_type=ModelType.GPT_3_5_TURBO,\n",
    "    model_config_dict=ChatGPTConfig().as_dict(),\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "7HsMPJrmGDrb"
   },
   "outputs": [],
   "source": [
    "# Set RolePlaying session\n",
    "\n",
    "role_play_session = RolePlaying(\n",
    "    assistant_role_name=\"Developer\",\n",
    "    user_role_name=\"CAMEL User\",\n",
    "    assistant_agent_kwargs=dict(\n",
    "        model=assistant_agent_model,\n",
    "        tools=tools,\n",
    "    ),\n",
    "    user_agent_kwargs=dict(\n",
    "        model=user_agent_model,\n",
    "    ),\n",
    "    task_prompt=task_prompt,\n",
    "    with_task_specify=False,\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "8M5RAC0BHAso",
    "outputId": "dfdf9c77-22e5-43b5-b542-00e0a5001885"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[32mAI Assistant sys message:\n",
      "BaseMessage(role_name='Developer', role_type=<RoleType.ASSISTANT: 'assistant'>, meta_dict={'task': 'I have created a new Github Repo,Please star my github repository: camel-ai/camel', 'assistant_role': 'Developer', 'user_role': 'CAMEL User'}, content='===== RULES OF ASSISTANT =====\\nNever forget you are a Developer and I am a CAMEL User. Never flip roles! Never instruct me!\\nWe share a common interest in collaborating to successfully complete a task.\\nYou must help me to complete the task.\\nHere is the task: I have created a new Github Repo,Please star my github repository: camel-ai/camel. Never forget our task!\\nI must instruct you based on your expertise and my needs to complete the task.\\n\\nI must give you one instruction at a time.\\nYou must write a specific solution that appropriately solves the requested instruction and explain your solutions.\\nYou must decline my instruction honestly if you cannot perform the instruction due to physical, moral, legal reasons or your capability and explain the reasons.\\nUnless I say the task is completed, you should always start with:\\n\\nSolution: <YOUR_SOLUTION>\\n\\n<YOUR_SOLUTION> should be very specific, include detailed explanations and provide preferable detailed implementations and examples and lists for task-solving.\\nAlways end <YOUR_SOLUTION> with: Next request.', video_bytes=None, image_list=None, image_detail='auto', video_detail='low')\n",
      "\n",
      "\u001b[34mAI User sys message:\n",
      "BaseMessage(role_name='CAMEL User', role_type=<RoleType.USER: 'user'>, meta_dict={'task': 'I have created a new Github Repo,Please star my github repository: camel-ai/camel', 'assistant_role': 'Developer', 'user_role': 'CAMEL User'}, content='===== RULES OF USER =====\\nNever forget you are a CAMEL User and I am a Developer. Never flip roles! You will always instruct me.\\nWe share a common interest in collaborating to successfully complete a task.\\nI must help you to complete the task.\\nHere is the task: I have created a new Github Repo,Please star my github repository: camel-ai/camel. Never forget our task!\\nYou must instruct me based on my expertise and your needs to solve the task ONLY in the following two ways:\\n\\n1. Instruct with a necessary input:\\nInstruction: <YOUR_INSTRUCTION>\\nInput: <YOUR_INPUT>\\n\\n2. Instruct without any input:\\nInstruction: <YOUR_INSTRUCTION>\\nInput: None\\n\\nThe \"Instruction\" describes a task or question. The paired \"Input\" provides further context or information for the requested \"Instruction\".\\n\\nYou must give me one instruction at a time.\\nI must write a response that appropriately solves the requested instruction.\\nI must decline your instruction honestly if I cannot perform the instruction due to physical, moral, legal reasons or my capability and explain the reasons.\\nYou should instruct me not ask me questions.\\nNow you must start to instruct me using the two ways described above.\\nDo not add anything else other than your instruction and the optional corresponding input!\\nKeep giving me instructions and necessary inputs until you think the task is completed.\\nWhen the task is completed, you must only reply with a single word <CAMEL_TASK_DONE>.\\nNever say <CAMEL_TASK_DONE> unless my responses have solved your task.', video_bytes=None, image_list=None, image_detail='auto', video_detail='low')\n",
      "\n",
      "\u001b[33mOriginal task prompt:\n",
      "I have created a new Github Repo,Please star my github repository: camel-ai/camel\n",
      "\n",
      "\u001b[36mSpecified task prompt:\n",
      "None\n",
      "\n",
      "\u001b[31mFinal task prompt:\n",
      "I have created a new Github Repo,Please star my github repository: camel-ai/camel\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# Print the system message and task prompt\n",
    "\n",
    "print(\n",
    "    Fore.GREEN\n",
    "    + f\"AI Assistant sys message:\\n{role_play_session.assistant_sys_msg}\\n\"\n",
    ")\n",
    "print(Fore.BLUE + f\"AI User sys message:\\n{role_play_session.user_sys_msg}\\n\")\n",
    "\n",
    "print(Fore.YELLOW + f\"Original task prompt:\\n{task_prompt}\\n\")\n",
    "print(\n",
    "    Fore.CYAN\n",
    "    + \"Specified task prompt:\"\n",
    "    + f\"\\n{role_play_session.specified_task_prompt}\\n\"\n",
    ")\n",
    "print(Fore.RED + f\"Final task prompt:\\n{role_play_session.task_prompt}\\n\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "6FyLdMcbFKqs",
    "outputId": "90e3101d-ac6f-494b-a74d-4c893e8ad736"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[34mAI User:\n",
      "\n",
      "Instruction: Visit the Github repository I created.\n",
      "Input: None\n",
      "\n",
      "\n",
      "\u001b[32mAI Assistant:\n",
      "\n",
      "Solution: To visit the Github repository you created, you can simply open a web browser and go to the following URL: https://github.com/camel-ai/camel\n",
      "\n",
      "Next request.\n",
      "\n",
      "\n",
      "\u001b[34mAI User:\n",
      "\n",
      "Instruction: Click on the \"Star\" button on the Github repository page.\n",
      "Input: None\n",
      "\n",
      "\n",
      "\u001b[32mAI Assistant:\n",
      "\n",
      "Function Execution: github_activity_star_repo_for_authenticated_user\n",
      "\tArgs: {'owner': 'camel-ai', 'repo': 'camel'}\n",
      "\tResult: {'execution_details': {'executed': True}, 'response_data': ''}\n",
      "\n",
      "Solution: I have successfully starred your Github repository \"camel-ai/camel\".\n",
      "\n",
      "Next request.\n",
      "\n",
      "\n",
      "\u001b[34mAI User:\n",
      "\n",
      "<CAMEL_TASK_DONE>\n",
      "\n",
      "\n",
      "\u001b[32mAI Assistant:\n",
      "\n",
      "Great! The task is completed. If you have any more tasks or need further assistance in the future, feel free to ask. Have a wonderful day!\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# Set terminate rule and print the chat message\n",
    "\n",
    "n = 0\n",
    "input_msg = role_play_session.init_chat()\n",
    "while n < 50:\n",
    "    n += 1\n",
    "    assistant_response, user_response = role_play_session.step(input_msg)\n",
    "\n",
    "    if assistant_response.terminated:\n",
    "        print(\n",
    "            Fore.GREEN\n",
    "            + (\n",
    "                \"AI Assistant terminated. Reason: \"\n",
    "                f\"{assistant_response.info['termination_reasons']}.\"\n",
    "            )\n",
    "        )\n",
    "        break\n",
    "    if user_response.terminated:\n",
    "        print(\n",
    "            Fore.GREEN\n",
    "            + (\n",
    "                \"AI User terminated. \"\n",
    "                f\"Reason: {user_response.info['termination_reasons']}.\"\n",
    "            )\n",
    "        )\n",
    "        break\n",
    "\n",
    "    # Print output from the user\n",
    "    print_text_animated(\n",
    "        Fore.BLUE + f\"AI User:\\n\\n{user_response.msg.content}\\n\"\n",
    "    )\n",
    "\n",
    "    # Print output from the assistant, including any function\n",
    "    # execution information\n",
    "    print_text_animated(Fore.GREEN + \"AI Assistant:\")\n",
    "    tool_calls: List[FunctionCallingRecord] = assistant_response.info[\n",
    "        'tool_calls'\n",
    "    ]\n",
    "    for func_record in tool_calls:\n",
    "        print_text_animated(f\"{func_record}\")\n",
    "    print_text_animated(f\"{assistant_response.msg.content}\\n\")\n",
    "\n",
    "    if \"CAMEL_TASK_DONE\" in user_response.msg.content:\n",
    "        break\n",
    "\n",
    "    input_msg = assistant_response.msg"
   ]
  }
 ],
 "metadata": {
  "colab": {
   "provenance": []
  },
  "kernelspec": {
   "display_name": "Python 3",
   "name": "python3"
  },
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}